package com.test.classload;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public final class JarClassLoader extends ClassLoader {
	private final String filename;

	public JarClassLoader(String filename) throws IOException {
		this.filename = filename;
	}

	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		JarFile jarFile = null;
		try {
			jarFile = new JarFile(filename);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		JarEntry entry = jarFile.getJarEntry(name.replace('.', '/') + ".class");
		if (entry == null) {
			throw new ClassNotFoundException(name);
		}
		InputStream in = null;
		try {
			byte[] array = new byte[1024];
			in = jarFile.getInputStream(entry);
			ByteArrayOutputStream out = new ByteArrayOutputStream(array.length);
			int length = in.read(array);
			while (length > 0) {
				out.write(array, 0, length);
				length = in.read(array);
			}
			return defineClass(name, out.toByteArray(), 0, out.size());
		} catch (IOException exception) {
			throw new ClassNotFoundException(name, exception);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (jarFile != null) {
				try {
					jarFile.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}
}